home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Informant Complete 1995 - 2000
/
Delphi Informant Complete 1995 to 2000.iso
/
Delphi Informant Magazine Complete Works SOURCE CODE 1998.rar
/
1998
/
Jul
/
di9807rl
/
grayform.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-02-24
|
4KB
|
146 lines
unit GrayForm;
{ Simple demonstration of Windows palettes.
Copyright ⌐ 1998 Tempest Software, Inc.
This program displays a gray scale gradation. It shows
the basic principles of creating and using Windows palettes
in Delphi.
}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
private
NumShades: Integer; // Number of distinct gray shades
Palette: HPalette; // Handle of the gray scale palette
procedure WmEraseBkgnd(var Msg: TWmEraseBkgnd); message Wm_EraseBkgnd;
protected
function GetPalette: HPalette; override;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormPaint(Sender: TObject);
var
I: Integer;
Rect: TRect;
Top: Integer;
OldPal: HPalette;
begin
// Tell Windows which palette to use when drawing the rectangles
OldPal := SelectPalette(Canvas.Handle, GetPalette, False);
try
// Fill a rectangle for each horizontal stripe. The horizontal limits
// are fixed, and update the top and bottom in the loop.
Rect.Left := 0;
Rect.Right := ClientWidth;
// To avoid gaps in coverage, increment Top as the top of the next stripe.
Top := 0;
for I := 1 to NumShades do
begin
Canvas.Brush.Color := PaletteIndex(I - 1);
Rect.Top := Top;
// The next top is the current bottom.
Top := I * ClientHeight div NumShades;
Rect.Bottom := Top;
Canvas.FillRect(Rect);
end;
finally
// Always restore the old palette
SelectPalette(Canvas.Handle, OldPal, True);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
LogPal: PLogPalette;
Gray: Byte;
I: Integer;
BitsPerPixel: Integer;
begin
// First determine the number of bits per pixel
if (GetDeviceCaps(Canvas.Handle, RasterCaps) and Rc_Palette) <> 0 then
BitsPerPixel := GetDeviceCaps(Canvas.Handle, ColorRes)
else
BitsPerPixel := GetDeviceCaps(Canvas.Handle, Planes) * GetDeviceCaps(Canvas.Handle, BitsPixel);
// Divide by 3 to get the number of distinct shades of each color
// element: red, green, blue. Then determine the number of colors.
NumShades := 1 shl (BitsPerPixel div 3);
// Tell the user how many gray shades the program will display.
Caption := Format('%s - %d Shades', [Caption, NumShades]);
// Allocate the logical palette. The LogPal record already has room
// for one color, so add enough memory for the remaining colors.
GetMem(LogPal, SizeOf(LogPal) + (NumShades-1)*SizeOf(TPaletteEntry));
try
LogPal.palVersion := $300; // required by Windows
LogPal.palNumEntries := NumShades;
for I := 0 to Pred(NumShades) do
begin
// Use a linear gray scale for simplicity. In a real graphics
// program, you should use a more sophisticated gray scale
// because the human eye does not respond linearly.
Gray := I * 255 div NumShades;
{$R- turn off because TLogPalette is defined stupidly}
LogPal.palPalEntry[I].peRed := Gray;
LogPal.palPalEntry[I].peGreen := Gray;
LogPal.palPalEntry[I].peBlue := Gray;
LogPal.palPalEntry[I].peFlags := 0;
{$R+}
end;
Palette := CreatePalette(LogPal^);
if Palette = 0 then
RaiseLastWin32Error;
finally
FreeMem(LogPal);
end;
end;
// Tell Delphi about the form's palette. Delphi will automatically
// select and realize the palette when Windows requires it.
function TForm1.GetPalette: HPalette;
begin
Result := Palette;
end;
// Free the palette.
procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteObject(Palette);
Palette := 0;
end;
// When the form changes size, make sure to repaint
// the entire window. Otherwise, only the expanded part
// gets redrawn, and the gradation looks wrong.
procedure TForm1.FormResize(Sender: TObject);
begin
Invalidate;
end;
// Tell Windows not to erase the background because the
// OnPaint handler will completely cover the form.
// This reduces the amount of flicker when repainting.
procedure TForm1.WmEraseBkgnd(var Msg: TWmEraseBkgnd);
begin
Msg.Result := 1;
end;
end.